package cheme.ProcessEditor.Parts.Equations;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.FlowLayoutEditPolicy;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.gef.requests.DropRequest;

import cheme.ProcessModel.Cmds.AddCmd;
import cheme.ProcessModel.Equations.Equation;
import cheme.ProcessModel.Equations.Equations;

public class PolicyEquationsLayout extends FlowLayoutEditPolicy
{
	/*
	 * Commands that may reasonably yields target feedback:
	 * REQ_ADD
	 * REQ_CLONE
	 * REQ_MOVE
	 * REQ_RESIZE_CHILDREN
	 * REQ_CREATE
	 */
	@Override
	protected void showLayoutTargetFeedback(Request request)
	{
	}
	
	/**
	 * @return <code>true</code> if the host's LayoutManager is in a horizontal orientation
	 */
	protected boolean isHorizontal()
	{
		IFigure figure = ((GraphicalEditPart)getHost()).getContentPane();
		return ((ToolbarLayout)figure.getLayoutManager()).isHorizontal();
	}
	
	protected int getFeedbackIndexFor(Request request)
	{
		/*
		 * If there is only an overall descriptor, show an insertionpoint at the 
		 * end of the full descriptor.
		 */
		if(1 == getHost().getChildren().size())
		{
			return -1;
		}
		
		/*
		 * If there are existing components, show the insertionpoint immediately
		 * after the overall component.
		 */
		
		return 1;
	}
	
	@Override
	protected Command createAddCommand(EditPart child, EditPart after)
	{
		return null;
	}

	@Override
	protected Command createMoveChildCommand(EditPart child, EditPart after)
	{
		return null;
	}

	@Override
	protected Command getCreateCommand(CreateRequest request)
	{
		Command cmd = null;
		
		Equations equations = (Equations)getHost().getModel();
		cmd = new AddCmd(new Equation(equations), equations.getEquationList(), 0); 
		
		return cmd;
	}
	
	private Point getLocationFromRequest(Request request)
	{
		return ((DropRequest)request).getLocation();
	}
	
	private Rectangle getAbsoluteBounds(GraphicalEditPart ep)
	{
		Rectangle bounds = ep.getFigure().getBounds().getCopy();
		ep.getFigure().translateToAbsolute(bounds);
		return bounds;
	}
	
//	/**
//	 * Shows an insertion line if there is one or more current children.
//	 * @see LayoutEditPolicy#showLayoutTargetFeedback(Request)
//	 */
//	protected void showLayoutTargetFeedback(Request request)
//	{
//		if (getHost().getChildren().size() == 0)
//		{
//			return;
//		}
//		
//		Polyline feedbackLine = getLineFeedback();
//		Transposer transposer = new Transposer();
//		transposer.setEnabled(!isHorizontal());
//		
//		boolean before = true;
//		int epIndex = getFeedbackIndexFor(request);
//		Rectangle r = null;
//		if (epIndex == -1)
//		{
//			before = false;
//			epIndex = getHost().getChildren().size() - 1;
//			EditPart editPart = (EditPart) getHost().getChildren().get(epIndex);
//			r = transposer.t(getAbsoluteBounds((GraphicalEditPart)editPart));
//		}
//		else
//		{
//			EditPart editPart = (EditPart) getHost().getChildren().get(epIndex);
//			r = transposer.t(getAbsoluteBounds((GraphicalEditPart)editPart));
//			Point p = transposer.t(getLocationFromRequest(request));
//			
//			if (p.x <= r.x + (r.width / 2))
//			{
//				before = true;
//			}
//			else
//			{
//				/*
//				 * We are not to the left of this Figure, so the emphasis line needs to be to
//				 * the right of the previous Figure, which must be on the previous row.
//				 */
//				before = false;
//				epIndex--;
//				editPart = (EditPart) getHost().getChildren().get(epIndex);
//				r = transposer.t(getAbsoluteBounds((GraphicalEditPart)editPart));
//			}
//		}
//		
//		int x = Integer.MIN_VALUE;
//		
//		if (before)
//		{
//			/* 
//			 * Want the line to be halfway between the end of the previous and the beginning
//			 * of this one. If at the begining of a line, then start halfway between the left
//			 * edge of the parent and the beginning of the box, but no more than 5 pixels (it
//			 * would be too far and be confusing otherwise).
//			 */
//			if (epIndex > 0)
//			{
//				// Need to determine if a line break.
//				Rectangle boxPrev = transposer.t(getAbsoluteBounds((GraphicalEditPart) getHost().getChildren().get(epIndex - 1)));
//				int prevRight = boxPrev.right();
//				if (prevRight < r.x)
//				{
//					// Not a line break
//					x = prevRight + (r.x - prevRight) / 2;
//				}
//				else if (prevRight == r.x)
//				{
//					x = prevRight + 1;
//				}
//			}
//			if (x == Integer.MIN_VALUE)
//			{
//				// It is a line break.
//				Rectangle parentBox = transposer.t(getAbsoluteBounds((GraphicalEditPart)getHost()));
//				x = r.x - 5;
//				
//				if (x < parentBox.x)
//				{
//					x = parentBox.x + (r.x - parentBox.x) / 2;
//				}
//			}
//		}
//		else
//		{
//			/* 
//			 * We only have before==false if we are at the end of a line, so go halfway
//			 * between the right edge and the right edge of the parent, but no more than 5
//			 * pixels.
//			 */
//			Rectangle parentBox = transposer.t(getAbsoluteBounds((GraphicalEditPart)getHost()));
//			int rRight = r.x + r.width;
//			int pRight = parentBox.x + parentBox.width;
//			x = rRight + 5;
//			
//			if (x > pRight)
//			{
//				x = rRight + (pRight - rRight) / 2;
//			}
//		}
//		
//		IFigure figure = ((GraphicalEditPart)getHost()).getContentPane();
//		int spacingOffset = ((ToolbarLayout)figure.getLayoutManager()).getSpacing();
//		
//		Point p1 = new Point(x, r.y - 4);
//		p1 = transposer.t(p1);
//		feedbackLine.translateToRelative(p1);
//		
//		Point p2 = new Point(x, r.y + r.height + 4);
//		p2 = transposer.t(p2);
//		feedbackLine.translateToRelative(p2);
//
//		p1.x += spacingOffset;
//		p1.y += spacingOffset;
//		
//		p2.x -= spacingOffset;
//		p2.y += spacingOffset;
//		
//		feedbackLine.setPoint(p1, 0);
//		feedbackLine.setPoint(p2, 1);
//	}
}